1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  package com.macvu.tiles;
63  
64  import com.macvu.tiles.cache.CacheObjectWrapper;
65  import com.macvu.tiles.capture.CacheHttpServletResponse;
66  import com.macvu.tiles.capture.CacheablesCaptureWrapper;
67  import org.apache.commons.logging.Log;
68  import org.apache.commons.logging.LogFactory;
69  import org.apache.struts.tiles.*;
70  
71  import javax.servlet.ServletContext;
72  import javax.servlet.ServletException;
73  import javax.servlet.http.HttpServletRequest;
74  import javax.servlet.http.HttpServletResponse;
75  import java.io.IOException;
76  
77  /***
78   * Created by IntelliJ IDEA.
79   * User: MVu
80   * Date: Mar 10, 2004
81   * Time: 2:09:10 PM
82   * <p/>
83   * Implement the Struts RequestProcessor that handle the cache TilesRequestProcessor.
84   * Need to handle the caching information.
85   * To use CacheTilesRequestProcessor add to struts-config: <controller processorClass="com.macvu.tiles.CacheTilesRequestProcessor" debug="0" contentType="text/html"/>
86   */
87  public class CacheTilesRequestProcessor extends TilesRequestProcessor {
88      /***
89       * Commons Logging instance.
90       */
91      protected static Log log = LogFactory.getLog(CacheTilesRequestProcessor.class);
92  
93      /***
94       * Process a Tile definition name.
95       * This method tries to process the parameter <code>definitionName</code> as a definition name.
96       * It returns <code>true</code> if a definition has been processed, or <code>false</code> otherwise.
97       * Parameter <code>contextRelative</code> is not used in this implementation.
98       *
99       * @param definitionName  Definition name to insert.
100      * @param contextRelative Is the definition marked contextRelative ?
101      * @param request         Current page request.
102      * @param response        Current page response.
103      * @return <code>true</code> if the method has processed uri as a definition name, <code>false</code> otherwise.
104      */
105     protected boolean processTilesDefinition(String definitionName, boolean contextRelative, HttpServletRequest request, HttpServletResponse response)
106             throws IOException, ServletException {
107         if (log.isDebugEnabled()) {
108             log.debug("doForward(" + definitionName + ")");
109         }
110         
111         boolean doInclude = false;
112         
113         Controller controller = null;
114         
115         String uri = null;
116         ComponentContext tileContext = null;
117 
118         CacheObjectWrapper cacheController = new CacheObjectWrapper();
119 
120         if (log.isDebugEnabled()) {
121             log.debug("Processing tile: " + definitionName);
122         }
123         try {
124             
125             
126             tileContext = ComponentContext.getContext(request);
127             doInclude = (tileContext != null);
128             ComponentDefinition definition;
129 
130             
131             
132             if (definitionsFactory != null) { 
133                 definition = definitionsFactory.getDefinition(definitionName, request, getServletContext());
134                 if (definition != null) { 
135                     
136                     
137                     uri = definition.getPath();
138                     controller = definition.getOrCreateController();
139                     if (tileContext == null) {
140                         tileContext = new ComponentContext(definition.getAttributes());
141                         ComponentContext.setContext(tileContext, request);
142                     } else {
143                         tileContext.addMissing(definition.getAttributes());
144                     }
145 
146                     ServletContext context = getServletContext();
147                     if (log.isDebugEnabled()) {
148                         log.debug("Tile " + definition.getName() + " is of type " + definition.getClass().getName());
149                     }
150                     if (definition instanceof CacheComponentDefinition) {
151                         if (log.isDebugEnabled()) {
152                             log.debug("definition is a Cache Component");
153                         }
154                         CacheInformation info = ((CacheComponentDefinition) definition).getCacheInformation();
155                         cacheController.initiateCacheInformation(context, info);
156 
157                         
158                         CacheablesCaptureWrapper cacheables = new CacheablesCaptureWrapper(context);
159                         if (cacheables.isEnableCapture()) {
160                             if (log.isDebugEnabled()) {
161                                 log.debug("Capture the component defintion");
162                             }
163                             cacheables.captureCacheablesForTile((CacheComponentDefinition) definition, request);
164                         }
165                     }
166                 } 
167             } 
168 
169             
170             definition = DefinitionsUtil.getActionDefinition(request);
171             if (definition != null) { 
172                 
173                 
174                 if (definition.getPath() != null) {
175                     uri = definition.getPath();
176                 }
177                 if (definition.getOrCreateController() != null) {
178                     controller = definition.getOrCreateController();
179                 }
180                 if (tileContext == null) {
181                     tileContext = new ComponentContext(definition.getAttributes());
182                     ComponentContext.setContext(tileContext, request);
183                 } else {
184                     tileContext.addMissing(definition.getAttributes());
185                 }
186             } 
187 
188 
189         } catch (java.lang.InstantiationException ex) {
190             if (log.isErrorEnabled()) {
191                 log.error("Can't create associated controller", ex);
192             }
193             throw new ServletException("Can't create associated controller", ex);
194         } catch (DefinitionsFactoryException ex) {
195             throw new ServletException(ex);
196         }
197 
198         
199         if (uri == null) {
200             return false;
201         }
202 
203         String key = null;
204 
205         if (cacheController.isCacheEnabled()) {
206             if (log.isDebugEnabled()) {
207                 log.debug("Caching is enable.  perform cache");
208             }
209             key = cacheController.getCacheKey(request);
210 
211             String cache = (String) cacheController.getCache(key);
212             if (cache == null) {
213                 CacheHttpServletResponse cacheResponse = new CacheHttpServletResponse(response);
214                 
215                 processTileSection(controller, tileContext, request, cacheResponse, uri, doInclude);
216 
217                 cacheController.putCache(key, cacheResponse.getCache());
218             } else {
219                 response.getWriter().write(cache);
220             }
221         } else {
222             processTileSection(controller, tileContext, request, response, uri, doInclude);
223         }
224 
225         return true;
226     }
227 
228     private void processTileSection(Controller controller, ComponentContext tileContext, HttpServletRequest request, HttpServletResponse response, String uri, boolean doInclude) throws ServletException, IOException {
229         
230         
231         if (controller != null) {
232             controller.perform(tileContext, request, response, getServletContext());
233         } 
234 
235         
236         
237         if (log.isDebugEnabled()) {
238             log.debug("uri=" + uri + " doInclude=" + doInclude);
239         }
240         if (doInclude) {
241             doInclude(uri, request, response);
242         } else {
243             doForward(uri, request, response);   
244         }
245     }
246 
247 }
248